﻿using Newtonsoft.Json;
using OddUserManager.Model;
using OddUserManager.Web.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace OddUserManager.Web.Common
{
    public class JCMatchUtils
    {

        /// <summary>
        /// 获取竞彩比赛某个结果的详细信息
        /// </summary>
        /// <param name="match"></param>
        /// <param name="option"></param>
        /// <returns></returns>
        public static JCResultAndOdd GetMatchBettingOption(JCMatch match, SelectedResult option)
        {
            JCResultAndOdd result = new JCResultAndOdd();
            //decimal payReturn = 0;
            var cutOdds = match.CutOddsList.OrderBy(p => p.SectionNumber).ToList();
            if ((int)option <= 3)
            {
                result.FixOdd = "0";
                var brqodds = match.JCHadOddsList.Where(p => p.MatchId == match.MatchId && p.FixedOdds.Equals(string.Empty)).ToList();
                if (null != brqodds && brqodds.Count > 0)
                {
                    var minSectionNumber = brqodds.Max(p => p.ReleaseTime);
                    var lastbrqOdds = match.JCHadOddsList.SingleOrDefault(p => p.MatchId == match.MatchId && p.ReleaseTime == minSectionNumber && p.FixedOdds.Equals(string.Empty));
                    if (lastbrqOdds != null)
                    {
                        switch (option)
                        {
                            case SelectedResult.胜:
                                result.PayReturn = Math.Round(cutOdds[0].MyCutWinChance * lastbrqOdds.HomeOdds / 100m, 2);
                                result.Result = SelectedResult.胜.ToString();
                                result.Odd = lastbrqOdds.HomeOdds;
                                break;
                            case SelectedResult.平:
                                result.PayReturn = Math.Round(cutOdds[0].MyCutDrawChance * lastbrqOdds.DrawOdds / 100m, 2);
                                result.Result = SelectedResult.平.ToString();
                                result.Odd = lastbrqOdds.DrawOdds;
                                break;
                            case SelectedResult.负:
                                result.PayReturn = Math.Round(cutOdds[0].MyCutLoseChance * lastbrqOdds.AwayOdds / 100m, 2);
                                result.Result = SelectedResult.负.ToString();
                                result.Odd = lastbrqOdds.AwayOdds;
                                break;
                        }
                    }
                }

            }
            else
            {
                var rqodds = match.JCHadOddsList.Where(p => p.MatchId == match.MatchId && !p.FixedOdds.Equals(string.Empty)).ToList();
                if (null != rqodds && rqodds.Count > 0)
                {
                    var minSectionNumber = rqodds.Max(p => p.ReleaseTime);
                    //判断让球情况
                    var lastOdds = match.JCHadOddsList.SingleOrDefault(p => p.MatchId == match.MatchId && p.ReleaseTime == minSectionNumber && !p.FixedOdds.Equals(string.Empty));
                    decimal winPayOut = 0;
                    decimal drawPayOut = 0;
                    decimal losePayOut = 0;
                    if (null != lastOdds)
                    {
                        result.FixOdd = lastOdds.FixedOdds;
                        switch (lastOdds.FixedOdds)
                        {
                            case "-4":
                                winPayOut = cutOdds[0].LetNegative4BallsMatchWinChance * lastOdds.HomeOdds / 100m;
                                drawPayOut = (cutOdds[0].LetNegative3BallsMatchWinChance - cutOdds[0].LetNegative4BallsMatchWinChance) * lastOdds.DrawOdds / 100m;
                                losePayOut = (10000 - cutOdds[0].LetNegative3BallsMatchWinChance) * lastOdds.AwayOdds / 100m;
                                break;
                            case "-3":
                                winPayOut = cutOdds[0].LetNegative3BallsMatchWinChance * lastOdds.HomeOdds / 100m;
                                drawPayOut = (cutOdds[0].LetNegative2BallsMatchWinChance - cutOdds[0].LetNegative3BallsMatchWinChance) * lastOdds.DrawOdds / 100m;
                                losePayOut = (10000 - cutOdds[0].LetNegative2BallsMatchWinChance) * lastOdds.AwayOdds / 100m;
                                break;
                            case "-2":
                                winPayOut = cutOdds[0].LetNegative2BallsMatchWinChance * lastOdds.HomeOdds / 100m;
                                drawPayOut = (cutOdds[0].LetNegative1BallsMatchWinChance - cutOdds[0].LetNegative2BallsMatchWinChance) * lastOdds.DrawOdds / 100m;
                                losePayOut = (10000 - cutOdds[0].LetNegative1BallsMatchWinChance) * lastOdds.AwayOdds / 100m;
                                break;
                            case "-1":
                                winPayOut = cutOdds[0].LetNegative1BallsMatchWinChance * lastOdds.HomeOdds / 100m;
                                drawPayOut = (cutOdds[0].MyCutWinChance - cutOdds[0].LetNegative1BallsMatchWinChance) * lastOdds.DrawOdds / 100m;
                                losePayOut = (10000 - cutOdds[0].MyCutWinChance) * lastOdds.AwayOdds / 100m;
                                break;
                            case "+1":
                                losePayOut = cutOdds[0].Let1BallsMatchWinChance * lastOdds.AwayOdds / 100m;
                                drawPayOut = (cutOdds[0].MyCutLoseChance - cutOdds[0].Let1BallsMatchWinChance) * lastOdds.DrawOdds / 100m;
                                winPayOut = (10000 - cutOdds[0].MyCutLoseChance) * lastOdds.HomeOdds / 100m;
                                break;
                            case "+2":
                                losePayOut = cutOdds[0].Let2BallsMatchWinChance * lastOdds.AwayOdds / 100m;
                                drawPayOut = (cutOdds[0].Let1BallsMatchWinChance - cutOdds[0].Let2BallsMatchWinChance) * lastOdds.DrawOdds / 100m;
                                winPayOut = (10000 - cutOdds[0].Let1BallsMatchWinChance) * lastOdds.HomeOdds / 100m;
                                break;
                            case "+3":
                                losePayOut = cutOdds[0].Let3BallsMatchWinChance * lastOdds.AwayOdds / 100m;
                                drawPayOut = (cutOdds[0].Let2BallsMatchWinChance - cutOdds[0].Let3BallsMatchWinChance) * lastOdds.DrawOdds / 100m;
                                winPayOut = (10000 - cutOdds[0].Let2BallsMatchWinChance) * lastOdds.HomeOdds / 100m;
                                break;
                        }
                        switch (option)
                        {
                            case SelectedResult.让球胜:
                                result.PayReturn = Math.Round(winPayOut, 2);
                                result.Result = SelectedResult.让球胜.ToString();
                                result.Odd = lastOdds.HomeOdds;
                                break;
                            case SelectedResult.让球平:
                                result.PayReturn = Math.Round(drawPayOut, 2);
                                result.Result = SelectedResult.让球平.ToString();
                                result.Odd = lastOdds.DrawOdds;
                                break;
                            case SelectedResult.让球负:
                                result.PayReturn = Math.Round(losePayOut, 2);
                                result.Result = SelectedResult.让球负.ToString();
                                result.Odd = lastOdds.AwayOdds;
                                break;
                        }
                    }
                }
            }
            return result;

        }

        public static bool CheckOddsRange(List<JCDetailOddFilteSetting> oddsList, decimal MatchResultOdds)
        {
            bool isChecked = false;
            if (null != oddsList && oddsList.Count > 0)
            {
                var childList = oddsList.Where(p => p.ParentId > 0).ToList();

                for (var i = 0; i < childList.Count; i++)
                {
                    var p = childList[i];
                    if (MatchResultOdds >= p.MinValue && MatchResultOdds < p.MaxValue)
                    {
                        isChecked = true;
                        break;
                    }
                }
            }
            return isChecked;
        }

        public static bool CheckLeagueIsExist(Dictionary<string, List<string>> selectedLeaguesList, JCMatch match)
        {
            bool isExist = false;
            if (null != selectedLeaguesList && selectedLeaguesList.Count > 0)
            {
                List<string> leaguesList = new List<string>();
                foreach (var i in selectedLeaguesList)
                {
                    leaguesList.AddRange(i.Value);
                }
                leaguesList = leaguesList.Distinct().ToList();
                if (leaguesList.Contains(match.TournamentName))
                {
                    isExist = true;
                }
            }
            return isExist;
        }
        private static int GetRqKey(string fixOdd, JCMatch currMatch)
        {
            int rq = 0;
            if (null == fixOdd || "" == fixOdd || "0" == fixOdd)
            {
                var cutOdd = currMatch.CutOddsList.SingleOrDefault(p => p.SectionNumber == currMatch.CutOddsList.Min(x => x.SectionNumber));
                if (null == cutOdd) { rq = 0; }
                if (cutOdd.CutWinChance > cutOdd.CutLoseChance)
                {
                    rq = (int)MatchFixOdds.主强;
                }
                else
                {
                    rq = (int)MatchFixOdds.客强;
                }
            }
            else
            {
                rq = int.Parse(fixOdd);
            }
            return rq;
        }

        /// <summary>
        /// 获取某一期比赛符合策略组的比赛结果
        /// </summary>
        /// <param name="matchData"></param>
        /// <param name="strategyGroups"></param>
        /// <returns></returns>
        public static List<JCLotteryBillSelectedMatchsTest> GetSelectedMatchResults(List<JCMatch> matchData, List<JCTestStrategyGroup> strategyGroups)
        {
            List<JCLotteryBillSelectedMatchsTest> list = new List<JCLotteryBillSelectedMatchsTest>();
            List<JCTestStrategy> strategys = new List<JCTestStrategy>();
            strategyGroups.ForEach(p =>
            {
                strategys.AddRange(p.JCTestStrategyRelationList.Select(x => x.JCTestStrategy));
            });
            foreach (SelectedResult option in Enum.GetValues(typeof(SelectedResult)))
            {
                bool isContainsOption = false;

                foreach (var str in strategys)
                {
                    // 选择的赛类集合
                    Dictionary<string, List<string>> selectedLeaguesList = JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(str.SelectedLeagues);
                    Dictionary<MatchFixOdds, List<string>> selectedMatchObjectList = JsonConvert.DeserializeObject<Dictionary<MatchFixOdds, List<string>>>(str.SelectedMatchObject);
                    //选择的赔率过滤
                    List<JCDetailOddFilteSetting> selectedFilterOddList = JsonConvert.DeserializeObject<List<JCDetailOddFilteSetting>>(str.SelectedOddsRange);

                    foreach (var i in selectedMatchObjectList)
                    {
                        if (option.ToString().Contains("让球"))
                        {
                            if ((int)i.Key != 100 && (int)i.Key != -100 && i.Value.Contains(option.ToString().Replace("让球", "")))
                            {
                                isContainsOption = true;
                                break;
                            }
                        }
                        else
                        {
                            if (((int)i.Key == 100 || (int)i.Key == -100) && i.Value.Contains(option.ToString()))
                            {
                                isContainsOption = true;
                                break;
                            }
                        }
                    }
                    if (isContainsOption)
                    {
                        break;
                    }

                }

                //如果比赛的这个选项不符合所有的策略，那么跳过所有比赛的这个投注选项
                if (!isContainsOption)
                { continue; }

                //循环比赛
                foreach (var i in matchData.OrderBy(p => p.Issue).ThenBy(p => p.MatchNumber).ToList())
                {

                    if (i.CutOddsList == null)
                    {
                        continue;
                    }
                    var oddOption = GetMatchBettingOption(i, option);
                    if (oddOption.Odd <= 0 || oddOption.Result == null || oddOption.Result == "")
                    {
                        continue;
                    }
                    List<JCTestStrategy> passJCTestStrategys = new List<JCTestStrategy>();
                    foreach (var str in strategys)
                    {
                        // 选择的赛类集合
                        Dictionary<string, List<string>> selectedLeaguesList = JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(str.SelectedLeagues);
                        Dictionary<MatchFixOdds, List<string>> selectedMatchObjectList = JsonConvert.DeserializeObject<Dictionary<MatchFixOdds, List<string>>>(str.SelectedMatchObject);
                        //选择的赔率过滤
                        List<JCDetailOddFilteSetting> selectedFilterOddList = JsonConvert.DeserializeObject<List<JCDetailOddFilteSetting>>(str.SelectedOddsRange);


                        var key = GetRqKey(oddOption.FixOdd, i);
                        var matchKey = (MatchFixOdds)key;



                        if (!(selectedMatchObjectList.ContainsKey(matchKey) && selectedMatchObjectList[matchKey].Contains(oddOption.Result.Replace("让球", ""))))
                        {
                            continue;
                        }

                        if (!(
                            CheckLeagueIsExist(selectedLeaguesList, i) &&
                            CheckOddsRange(selectedFilterOddList, oddOption.Odd)
                            && oddOption.PayReturn >= str.FinalMinPayOut && oddOption.PayReturn < str.FinalMaxPayOut
                            ))
                        {
                            continue;
                        }

                        passJCTestStrategys.Add(str);
                    }
                    if (passJCTestStrategys.Count > 0)
                    {
                        //创建通过帅选的比赛的集合
                        var selectedMatch = list.SingleOrDefault(p => p.SelectedMatchId == i.MatchId.ToString());
                        if (null == selectedMatch)
                        {
                            selectedMatch = new JCLotteryBillSelectedMatchsTest();
                            selectedMatch.TestNumber = "";
                            selectedMatch.SelectedMatchId = i.MatchId.ToString();
                            selectedMatch.SelectedGameNumber = i.Issue;
                            selectedMatch.LeagueName = i.TournamentName;
                            selectedMatch.TestNumber = "";
                            list.Add(selectedMatch);
                        }
                        JCLotteryBillSelectedMatchResultsTest resutTest = new JCLotteryBillSelectedMatchResultsTest();

                        if (selectedMatch.ResultList.Count(x => x.SelectedResult == oddOption.Result && x.FixOdds == oddOption.FixOdd && x.SelectedOdds == oddOption.Odd) == 0)
                        {

                            resutTest.SelectedResult = oddOption.Result;
                            resutTest.SelectedOdds = oddOption.Odd;
                            resutTest.FixOdds = oddOption.FixOdd;
                            resutTest.SelectedPayOut = oddOption.PayReturn;
                            resutTest.DetailsOddCount = 0;
                            resutTest.CoefficientOfStrategy = passJCTestStrategys.OrderByDescending(p => p.CoefficientOfStrategy).ThenBy(p => p.Reliability).First().CoefficientOfStrategy;
                            resutTest.Reliability = passJCTestStrategys.OrderByDescending(p => p.CoefficientOfStrategy).ThenBy(p => p.Reliability).First().Reliability;
                            selectedMatch.ResultList.Add(resutTest);
                        }
                    }



                }
            }
            return list;
        }
    }
}
